import os
from openpyxl import load_workbook  
import sys
import re
sys.path.append("../")
sys.path.append("../testRail")
# import qcriREST.application.qcrest as qcrest
from sys import argv
# from qcriREST import const
from testRail import testrailRobot


"""Function to convert test case from quality center to robot scripts
   There are two ways implement this function
   1. export test case in test plan to excel file.
      convert excel file to robot scritps
      Usage:
           python converter.py BellaMa 'C:\\Workspace\\Robot\\tango\\50_TANGO_Acceptance_Test\\NewCases\\IF(Interface)'
      Note:The default tag value is "P1",need to modify manually for tag value
   2. provide a case list, query test case from quality center and generate robot scripts   
      Be attention that case name is fuzzy matching. If completed case name is can't be found ,
      then this case converting will be failed
      Usage:
           python converter.py BellaMa
           python converter.py BellaMa 'C:\\Workspace\\Robot\\tango\\50_TANGO_Acceptance_Test\\new.txt'
 """

ROBOT_SETTINGS = "*** Settings ***"
ROBOT_SETTINGS_DOC = "Documentation"
ROBOT_SETTINGS_Source = "Resource    Keywords/Common_Head.robot"
ROBOT_SETTINGS_Meta_AUTHOR = "Metadata    Author    "
ROBOT_SETTINGS_Meta_ID = "Metadata    ID    "
ROBOT_SETTINGS_Tag = "Force Tags    "
ROBOT_TESTCASE = "*** Test Cases ***"
ROBOT_KEYWORD = "*** Keywords ***"
class Converter(object):

      def generate_robot_script(self, file_name, steps, author,id,case_priority):
          with open(file_name, 'w', encoding='utf-8') as fileobj:
              case_name = os.path.basename(file_name).replace(".robot", "")
              self.generate_header(fileobj, case_name, author, id, case_priority)
              self.generate_case_steps(fileobj,steps)
              self.generate_keywords(fileobj, steps)


## the default tag is "P1". If convert case from excel, please manually modified the tag value
      def generate_header(self, file_obj, case_name,author,id,case_priority):
          file_obj.write(ROBOT_SETTINGS + '\n')
          file_obj.write(ROBOT_SETTINGS_DOC + "    " + case_name + '\n')
          file_obj.write(ROBOT_SETTINGS_Source + '\n')
          priority_dict={
            4:"P1",  #Critical
            3:"P2",  #Major
            2:"P3",  #Medium
            1:"P4",  #Minor
        }
          case_tag=priority_dict[case_priority]
          file_obj.write(ROBOT_SETTINGS_Tag + case_tag + '\n')
          file_obj.write(ROBOT_SETTINGS_Meta_AUTHOR + author+ '\n')
          file_obj.write(ROBOT_SETTINGS_Meta_ID + str(id)+ '\n\n\n')
          file_obj.write(ROBOT_TESTCASE + '\n')
          file_obj.write(case_name + '\n')

      def generate_case_steps(self,file_obj,stepData):
          for index,step in enumerate(stepData):
              ##generate keyword according to first line in description
              description = step["content"].split("\n")
              kwName = description[0];
              kwName = re.sub(r'\s+', ' ', kwName)
              kwName = kwName.replace("{", "").replace("}", "")
              ### change kw to camel style
              kwName = ' '.join(word[0].upper() + word[1:] for word in kwName.split())
              nameArray = self.group_string_by_length(kwName.strip())
              kwName = nameArray[0]
              kwName=kwName.strip()
              file_obj.write("    "+"Step {}".format(index+1)+' '+kwName+ '\n')


      def generate_keywords(self,file_obj,steps):
          file_obj.write('\n\n\n'+ROBOT_KEYWORD + '\n')
          for index,stepData in enumerate(steps):
            ##generate keyword according to first line in description
            kwName = ""
            description = stepData["content"].split("\n")
            kwName = description[0];
            kwName = re.sub(r'\s+', ' ', kwName)
            kwName = kwName.replace("{", "").replace("}", "")
            ### change kw to camel style
            kwName = ' '.join(word[0].upper() + word[1:] for word in kwName.split())
            nameArray = self.group_string_by_length(kwName.strip())
            kwName = nameArray[0]
            kwName=kwName.strip()
            file_obj.write("Step" + ' ${step} ' + kwName + '\n')
            file_obj.write("    #************************" + "Step {}".format(index+1) + "******************************" + '\n')
            file_obj.write("    #  Do:" + '\n')

            for line in description:
                if ''!=line.strip() and None!=line.strip():    ## if blank line, the skip
                    lineArray = self.group_string_by_length(line.strip())
                    for signleline in lineArray:
                        file_obj.write("    #     " + signleline + '\n')
            file_obj.write("    #  Expected:" + '\n')
            expected_result = stepData["expected"].split("\n")
            for line in expected_result:
                if ''!=line.strip() and None!=line.strip():  ## if blank line, the skip
                    lineArray = self.group_string_by_length(line.strip())
                    for signleline in lineArray:
                        file_obj.write("    #     " + signleline + '\n')
            file_obj.write("    #************************************************************" + '\n\n\n')

      def get_excel_data(self,fileName):
          workbook = load_workbook(filename=fileName)  
          # 选择活动工作表  
          sheet = workbook.active  
          cell_value = sheet['A1'].value  
          ExcelData = []
          # 遍历所有行和列  
          for row in sheet.iter_rows(min_row=1, max_col=3, values_only=True):  
            array = {'StepName':'','Description':'','Expected Result':''}
            array['StepName'] = row[0]
            array['Description'] = row[1]
            array['Expected Result'] = row[2]
            ExcelData.append(array)
          return ExcelData

      def convert_from_excel(self, dirpath,author):
          for dirpath, dirnames, filenames in os.walk(dirpath):
              for filename in filenames:
                  if filename.endswith(".xlsx"):
                      case_filename = os.path.join(dirpath,filename)
                      ExcelData = self.get_excel_data(case_filename)
                      robot_filename = os.path.join(case_filename.replace(".xlsx", ".robot"))
                      self.generate_robot_script(robot_filename, ExcelData,author)

      def query_test_step(self,test_case_list):
        result = []
        for test_case in test_case_list:
            test_case_steps = testrailRobot.TestRail().get_case_by_id(test_case)
            if test_case_steps:
                result.append(test_case_steps)
        return result
            
            

      def convert_from_testrail(self,filename,author):
          test_case_list = []
          dirpath = os.path.dirname(os.path.abspath(filename))
          with open(filename, 'r') as fileobj:
              while True:
                  line = fileobj.readline()
                  if line.endswith("\n"):
                     line = line[:-1]  # remove /n
                  if line:
                      test_case_list.append(line)
                  else:
                      break
          test_step_collection = self.query_test_step(test_case_list)
          for test_case in test_step_collection:
              case_name=test_case["title"].replace("'","").replace('"',"").replace("/"," ")
              robot_filename = os.path.join(dirpath, case_name + ".robot")
              self.generate_robot_script(robot_filename, test_case["custom_steps_separated"],author,test_case["id"],test_case["priority_id"])
    
    
      def group_string_by_length(self,s, max_length=55):
              # 使用正则表达式匹配单词边界
            words = re.findall(r'\b\w+\b', s)
            grouped_strings = []
            current_group = ''
            for word in words:
                if len(current_group + word) > max_length:
                    grouped_strings.append(current_group)
                    current_group = word
                else:
                    current_group += ' ' + word  # 保留单词间的空格
            grouped_strings.append(current_group)
            return grouped_strings    

##example
##1. convert case from qc, case list is existed in Debug\Converter\case_list.txt
##python converter.py BellaMa
##2.convert case from qc, case list is the second argument
##python converter.py BellaMa "C:\Workspace\Robot\tango\50_TANGO_Acceptance_Test\NewCases\IF(Interface)\new.txt"
##3.convert case from Excel,excel folder is the second argument
##python converter.py BellaMa "C:\Workspace\Robot\tango\50_TANGO_Acceptance_Test\NewCases\IF(Interface)"
if __name__ == "__main__":
      ct = Converter()
      author = argv[1]
      dirpath =  ""
      ## Default path is ${tango_project}\Debug\Converter\case_list.txt
      if len(argv)==2:
          path = os.path.abspath(os.path.join(os.getcwd(), "../.."))
          dirpath = os.path.join(path,"Debug\Converter\case_list.txt")
      else:
          dirpath = argv[2]
      ##if given path is a directory, then convert all excel files to robot scripts
      ##else, query test case and generate robot scritps
      if os.path.isdir(dirpath):
         ct.convert_from_excel(dirpath, author)
      else:
         ct.convert_from_testrail(dirpath, author)
      print("Converting is done")